import { DicomService } from './DicomService';
import ParameterCalculator from './ParameterCalculator';

class ImageProcessor {
  constructor(dicomData, options = {}) {
    this.dicomData = dicomData;
    this.pixelDataArray = [];
    this.processedResults = {};
    this.options = {
      enableInvert: true, // 默认启用反转
      frameRange: { start: 1, end: 1 }, // 默认帧范围
      enableVesselExtraction: false, // 默认不启用血管区域提取
      vesselMask: null, // 外部提供的血管mask
      processingMethod: 'normal', // 处理方法：normal | maximum_slope
      arterialInputPoint: null, // 动脉输入点标记
      onProgress: null, // 进度回调函数
      ...options
    };
    
    // 如果没有指定帧范围，使用全部帧
    if (!this.options.frameRange || this.options.frameRange.start === this.options.frameRange.end === 1) {
      const totalFrames = this.dicomData.isMultiFrame 
        ? this.dicomData.metadata.numberOfFrames 
        : this.dicomData.images?.length || 1;
      this.options.frameRange = { start: 1, end: totalFrames };
    }
    
    console.log('ImageProcessor 初始化:', this.options);
    
    // 初始化参数计算器
    this.parameterCalculator = new ParameterCalculator();
  }

  async processAll() {
    console.log('开始图像处理...');
    
    // 报告进度的辅助函数
    const reportProgress = (progress, step) => {
      if (this.options.onProgress) {
        this.options.onProgress(progress, step);
      }
    };
    
    // 提取所有图像的像素数据
    reportProgress(5, '正在提取像素数据...');
    await this.extractAllPixelData();
    
    // 如果启用了血管区域提取，使用外部提供的mask或创建新的血管区域掩膜
    if (this.options.enableVesselExtraction) {
      reportProgress(15, '正在处理血管区域...');
      this.vesselMask = this.options.vesselMask?.mask || this.createVesselMask();
      if (this.options.vesselMask?.mask) {
        console.log('使用外部提供的血管Mask');
      }
    } else {
      this.vesselMask = null;
    }
    
    // 根据处理方法选择计算参数
    let processedResults;
    
    if (this.options.processingMethod === 'maximum_slope') {
      // 最大斜率法计算
      reportProgress(25, '使用最大斜率法计算参数...');
      console.log('使用最大斜率法计算参数...');
      processedResults = await this.calculateMaximumSlopeParameters(reportProgress);
    } else {
      // 普通方法计算
      reportProgress(25, '开始计算医学参数...');
      console.log('使用普通方法计算参数...');
      
      reportProgress(30, '正在计算 TTP (达峰时间)...');
      const ttp = await this.calculateTTP();
      
      reportProgress(45, '正在计算 MTT (平均通过时间)...');
      const mtt = await this.calculateMTT();
      
      reportProgress(60, '正在计算 PH (峰值高度)...');
      const ph = await this.calculatePH();
      
      reportProgress(75, '正在计算 AUC (曲线下面积)...');
      const auc = await this.calculateAUC();
      
      reportProgress(85, '正在计算 CBF (脑血流)...');
      const cbf = await this.calculateCBF();
      
      reportProgress(95, '正在计算 CBV (脑血容量)...');
      const cbv = await this.calculateCBV();
      
      processedResults = { ttp, mtt, ph, auc, cbf, cbv };
    }

    this.processedResults = processedResults;
    reportProgress(100, '处理完成');
    console.log('图像处理完成:', this.processedResults);
    
    return this.processedResults;
  }

  async extractAllPixelData() {
    this.pixelDataArray = [];
    
    const { start, end } = this.options.frameRange;
    console.log(`开始提取像素数据，帧范围: ${start} - ${end}`);
    
    // 检查是否为多帧DICOM数据
    if (this.dicomData.isMultiFrame) {
      console.log('处理多帧DICOM数据...');
      
      // 只处理指定帧范围内的数据
      for (let frameIndex = start - 1; frameIndex < end && frameIndex < this.dicomData.images.length; frameIndex++) {
        const imageData = this.dicomData.images[frameIndex];
        
        try {
          let pixelData;
          
          // 从多帧DICOM提取像素数据
          if (imageData.dataSet && imageData.dataSet.pixelData) {
            pixelData = {
              data: imageData.dataSet.pixelData,
              rows: imageData.rows,
              columns: imageData.columns,
              bitsAllocated: 16,
              bitsStored: 16,
              pixelRepresentation: 0
            };
          } else {
            throw new Error('多帧DICOM数据格式错误');
          }
          
          // 对像素数据进行反转处理（DSA图像通常需要反转）
          const invertedData = this.invertPixelData(pixelData.data, pixelData.bitsAllocated);
          
          this.pixelDataArray.push({
            ...pixelData,
            data: invertedData, // 使用反转后的数据
            frameNumber: frameIndex,
            acquisitionTime: imageData.acquisitionTime,
            instanceNumber: imageData.instanceNumber
          });
          
        } catch (error) {
          console.error(`提取第${frameIndex}帧像素数据失败:`, error);
          throw error;
        }
      }
      
      console.log(`成功提取多帧DICOM数据: ${this.pixelDataArray.length} 帧`);
    } else {
      // 原有的多文件序列处理逻辑
      const framesToProcess = this.dicomData.images.slice(start - 1, end);
      for (const imageData of framesToProcess) {
        try {
          let pixelData;
          
          // 检查是否是演示数据格式
          if (imageData.dataSet && imageData.dataSet.pixelData) {
            // 演示数据格式
            pixelData = {
              data: imageData.dataSet.pixelData,
              rows: imageData.rows,
              columns: imageData.columns,
              bitsAllocated: 16,
              bitsStored: 16,
              pixelRepresentation: 0
            };
          } else if (imageData.dataSet && imageData.dataSet.elements) {
            // 真实DICOM数据格式
            pixelData = await DicomService.extractPixelData(imageData.dataSet);
          } else {
            throw new Error('无法识别的图像数据格式');
          }
          
          // 对像素数据进行反转处理
          const invertedData = this.invertPixelData(pixelData.data, pixelData.bitsAllocated);
          
          this.pixelDataArray.push({
            ...pixelData,
            data: invertedData, // 使用反转后的数据
            acquisitionTime: imageData.acquisitionTime,
            instanceNumber: imageData.instanceNumber
          });
        } catch (error) {
          console.error('提取像素数据失败:', error);
          throw error;
        }
      }
    }

    // 按时间或帧号排序
    this.pixelDataArray.sort((a, b) => {
      if (a.frameNumber !== undefined && b.frameNumber !== undefined) {
        return a.frameNumber - b.frameNumber;
      }
      return parseInt(a.instanceNumber) - parseInt(b.instanceNumber);
    });
    
    console.log(`图像数据提取完成: ${this.pixelDataArray.length} 帧 (第${start}-${end}帧), 尺寸: ${this.pixelDataArray[0]?.rows}x${this.pixelDataArray[0]?.columns}${this.options.enableInvert ? ' (已反转)' : ' (未反转)'}`);
    
    // 验证时间密度曲线数据完整性
    this.validateTimeSeriesData();
    
    // 计算真实时间间隔
    this.calculateTimeIntervals();
  }

  // 修改：像素数据反转方法，支持配置控制
  invertPixelData(originalData, bitsAllocated = 16) {
    // 如果未启用反转，直接返回原始数据
    if (!this.options.enableInvert) {
      console.log('图像反转已禁用，跳过反转步骤');
      return originalData;
    }
    
    try {
      console.log('正在反转像素数据...');
      
      // 确定最大值
      const maxValue = Math.pow(2, bitsAllocated) - 1;
      
      // 创建反转后的数据数组
      const invertedData = new originalData.constructor(originalData.length);
      
      // 对每个像素进行反转：new_value = max_value - old_value
      for (let i = 0; i < originalData.length; i++) {
        invertedData[i] = maxValue - originalData[i];
      }
      
      console.log(`像素数据反转完成: ${originalData.length} 个像素, 最大值: ${maxValue}`);
      return invertedData;
      
    } catch (error) {
      console.error('像素数据反转失败:', error);
      // 如果反转失败，返回原始数据
      return originalData;
    }
  }

  // 新增：验证时间序列数据的完整性
  validateTimeSeriesData() {
    if (this.pixelDataArray.length < 3) {
      console.warn('时间序列帧数过少，可能影响参数计算精度');
    }
    
    const { rows, columns } = this.pixelDataArray[0];
    const pixelsPerFrame = rows * columns;
    
    // 检查每帧数据完整性
    for (let frameIndex = 0; frameIndex < this.pixelDataArray.length; frameIndex++) {
      const frame = this.pixelDataArray[frameIndex];
      if (frame.data.length !== pixelsPerFrame) {
        console.error(`第${frameIndex}帧像素数据不完整: 期望${pixelsPerFrame}, 实际${frame.data.length}`);
      }
    }
    
    console.log(`时间序列验证完成: ${this.pixelDataArray.length}帧, 每帧${pixelsPerFrame}像素`);
  }

  // 新增：计算真实时间间隔
  calculateTimeIntervals() {
    // 优先使用DICOM帧率信息
    if (this.dicomData.metadata?.frameRate && parseFloat(this.dicomData.metadata.frameRate) > 0) {
      const frameRate = parseFloat(this.dicomData.metadata.frameRate);
      const timeInterval = 1.0 / frameRate; // 每帧的时间间隔（秒）
      console.log(`使用DICOM帧率计算时间间隔: ${frameRate} fps, 间隔: ${timeInterval.toFixed(3)}s`);
      
      // 生成时间数组
      this.timeArray = [];
      for (let i = 0; i < this.pixelDataArray.length; i++) {
        this.timeArray.push(i * timeInterval);
      }
      this.timeUnit = '秒';
      this.timeInterval = timeInterval;
      
      // 设置参数计算器的时间数组
      this.parameterCalculator.setTimeArray(this.timeArray);
      return;
    }

    // 尝试使用Frame Time标签
    if (this.dicomData.metadata?.frameTime && parseFloat(this.dicomData.metadata.frameTime) > 0) {
      const frameTimeMs = parseFloat(this.dicomData.metadata.frameTime);
      const timeInterval = frameTimeMs / 1000.0; // 转换为秒
      console.log(`使用Frame Time计算时间间隔: ${frameTimeMs}ms, 间隔: ${timeInterval.toFixed(3)}s`);
      
      this.timeArray = [];
      for (let i = 0; i < this.pixelDataArray.length; i++) {
        this.timeArray.push(i * timeInterval);
      }
      this.timeUnit = '秒';
      this.timeInterval = timeInterval;
      
      // 设置参数计算器的时间数组
      this.parameterCalculator.setTimeArray(this.timeArray);
      return;
    }

    // 尝试使用采集时间信息
    const hasAcquisitionTime = this.pixelDataArray.some(frame => frame.acquisitionTime);
    if (hasAcquisitionTime) {
      console.log('使用采集时间信息计算时间间隔');
      this.timeArray = [];
      let baseTime = null;
      
      for (let i = 0; i < this.pixelDataArray.length; i++) {
        const frame = this.pixelDataArray[i];
        if (frame.acquisitionTime) {
          // 使用DicomService的时间解析方法
          const timeInSeconds = this.parseAcquisitionTime(frame.acquisitionTime);
          if (baseTime === null) {
            baseTime = timeInSeconds;
          }
          this.timeArray.push(timeInSeconds - baseTime);
        } else {
          this.timeArray.push(i); // 降级到帧索引
        }
      }
      this.timeUnit = '秒';
      const avgInterval = this.timeArray.length > 1 ? 
        (this.timeArray[this.timeArray.length - 1] - this.timeArray[0]) / (this.timeArray.length - 1) : 1.0;
      this.timeInterval = avgInterval;
      console.log(`基于采集时间计算平均时间间隔: ${avgInterval.toFixed(3)}s`);
      
      // 设置参数计算器的时间数组
      this.parameterCalculator.setTimeArray(this.timeArray);
      return;
    }

    // 降级到帧索引（默认1秒间隔）
    console.log('无法获取时间信息，使用帧索引（默认1秒间隔）');
    this.timeArray = [];
    for (let i = 0; i < this.pixelDataArray.length; i++) {
      this.timeArray.push(i);
    }
    this.timeUnit = '帧';
    this.timeInterval = 1.0;
    
    // 设置参数计算器的时间数组
    this.parameterCalculator.setTimeArray(this.timeArray);
  }

  // 解析DICOM采集时间
  parseAcquisitionTime(acquisitionTime) {
    try {
      const timeStr = acquisitionTime.toString();
      if (timeStr.length >= 6 && /^\d+\.?\d*$/.test(timeStr)) {
        // DICOM时间格式 HHMMSS.FFFFFF
        const hours = parseInt(timeStr.substr(0, 2)) || 0;
        const minutes = parseInt(timeStr.substr(2, 2)) || 0;
        const seconds = parseFloat(timeStr.substr(4)) || 0;
        return hours * 3600 + minutes * 60 + seconds;
      } else {
        // 其他数值格式
        return parseFloat(timeStr) || 0;
      }
    } catch (error) {
      console.warn('解析采集时间失败:', error);
      return 0;
    }
  }

  // 安全地计算数组的最小值和最大值，避免栈溢出
  getMinMax(data) {
    let min = Infinity;
    let max = -Infinity;
    
    for (let i = 0; i < data.length; i++) {
      const value = data[i];
      if (value < min) min = value;
      if (value > max) max = value;
    }
    
    return { min, max };
  }

  // ===================== 通用辅助方法 =====================

  // 通用方法：创建参数图结果对象
  createParameterResult(parameterData, config) {
    const { rows, columns } = this.pixelDataArray[0];
    
    // 如果启用了血管区域提取，应用血管区域掩膜
    let finalData = parameterData;
    if (this.vesselMask) {
      finalData = new Float32Array(parameterData.length);
      for (let i = 0; i < parameterData.length; i++) {
        finalData[i] = this.vesselMask[i] ? parameterData[i] : 0;
      }
      console.log(`${config.name}已应用血管区域掩膜`);
    }
    
    const { min, max } = this.getMinMax(finalData);
    console.log(`${config.name}计算完成: 范围 ${min.toFixed(config.precision || 2)} - ${max.toFixed(config.precision || 2)} ${config.units}`);

    // 归一化数据用于显示
    const normalizedData = this.normalizeDataForDisplay(finalData);

    return {
      data: normalizedData,
      originalData: finalData,
      width: columns,
      height: rows,
      colorMap: config.colorMap || 'jet',
      units: config.units,
      description: config.description,
      min: min,
      max: max,
      physicalUnit: config.physicalUnit || config.units,
      timeInterval: this.timeInterval
    };
  }

  // ===================== 重构后的参数计算方法 =====================

  async calculateTTP() {
    // Time To Peak - 到达峰值的时间
    console.log('计算TTP (Time To Peak)...');
    
    if (this.pixelDataArray.length === 0) {
      throw new Error('没有可用的像素数据');
    }

    const { rows, columns } = this.pixelDataArray[0];
    const ttpData = new Float32Array(rows * columns);

    console.log(`开始计算TTP: ${rows}x${columns} 像素, 时间单位: ${this.timeUnit}`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算峰值位置
      const { peakIndex } = this.parameterCalculator.calculatePeak(correctedCurve);

      // 使用真实时间而不是帧索引
      ttpData[pixelIndex] = this.timeArray[peakIndex];
    }

    // 创建并返回结果
    return this.createParameterResult(ttpData, {
      name: 'TTP',
      units: this.timeUnit,
      description: `Time To Peak (${this.timeUnit})`,
      physicalUnit: this.timeUnit,
      colorMap: 'jet',
      precision: 3
    });
  }

  async calculateMTT() {
    // Mean Transit Time - 平均通过时间
    console.log('计算MTT (Mean Transit Time)...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const mttData = new Float32Array(rows * columns);

    console.log(`开始计算MTT: ${rows}x${columns} 像素, 时间单位: ${this.timeUnit}`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算MTT（时间重心）
      mttData[pixelIndex] = this.parameterCalculator.calculateMTT(correctedCurve);
    }

    // 创建并返回结果
    return this.createParameterResult(mttData, {
      name: 'MTT',
      units: this.timeUnit,
      description: `Mean Transit Time (${this.timeUnit})`,
      physicalUnit: this.timeUnit,
      colorMap: 'hot',
      precision: 3
    });
  }

  async calculatePH() {
    // Peak Height - 峰值高度
    console.log('计算PH (Peak Height)...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const phData = new Float32Array(rows * columns);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算峰值高度
      const { peakValue } = this.parameterCalculator.calculatePeak(correctedCurve);
      
      // PH = 峰值（已经减去基线）
      phData[pixelIndex] = Math.max(0, peakValue);
    }

    // 创建并返回结果
    return this.createParameterResult(phData, {
      name: 'PH',
      units: 'intensity',
      description: 'Peak Height',
      physicalUnit: 'Intensity Units',
      colorMap: 'jet',
      precision: 2
    });
  }

  async calculateAUC() {
    // Area Under Curve - 曲线下面积
    console.log('计算AUC (Area Under Curve)...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const aucData = new Float32Array(rows * columns);

    console.log(`开始计算AUC: ${rows}x${columns} 像素, 时间单位: ${this.timeUnit}`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算曲线下面积
      aucData[pixelIndex] = this.parameterCalculator.calculateAUC(correctedCurve);
    }

    // 创建并返回结果
    return this.createParameterResult(aucData, {
      name: 'AUC',
      units: `intensity·${this.timeUnit}`,
      description: `Area Under Curve (强度·${this.timeUnit})`,
      physicalUnit: `Intensity·${this.timeUnit}`,
      colorMap: 'viridis',
      precision: 3
    });
  }

  async calculateCBF() {
    // Cerebral Blood Flow - 脑血流量
    console.log('计算CBF (Cerebral Blood Flow)...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const cbfData = new Float32Array(rows * columns);

    console.log(`开始计算CBF: ${rows}x${columns} 像素, 时间单位: ${this.timeUnit}`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算峰值和MTT
      const { peakValue } = this.parameterCalculator.calculatePeak(correctedCurve);
      const mtt = this.parameterCalculator.calculateMTT(correctedCurve);
      
      // CBF = Peak / MTT，单位调整为ml/100g/min
      const cbf = mtt > 0 ? (peakValue / mtt) * 60 : 0; // 转换为每分钟
      cbfData[pixelIndex] = cbf;
    }

    // 创建并返回结果
    return this.createParameterResult(cbfData, {
      name: 'CBF',
      units: 'ml/100g/min',
      description: 'Cerebral Blood Flow (ml/100g/min)',
      physicalUnit: 'ml/100g/min',
      colorMap: 'rainbow',
      precision: 2
    });
  }

  // 计算TDC曲线变化幅度，用于血管区域提取
  calculateTDCVariation(timeCurve) {
    if (!timeCurve || timeCurve.length < 2) {
      return 0;
    }
    
    try {
      // 计算曲线的标准差作为变化幅度指标
      const mean = timeCurve.reduce((sum, val) => sum + val, 0) / timeCurve.length;
      const variance = timeCurve.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / timeCurve.length;
      const stdDev = Math.sqrt(variance);
      
      // 也可以使用峰值和最小值之间的差值
      let min = Infinity;
      let max = -Infinity;
      for (let i = 0; i < timeCurve.length; i++) {
        const value = timeCurve[i];
        if (value < min) min = value;
        if (value > max) max = value;
      }
      const range = max - min;
      
      // 使用标准差和范围的组合作为变化幅度
      return stdDev * 0.7 + range * 0.3;
    } catch (error) {
      console.error('计算TDC变化幅度失败:', error);
      return 0;
    }
  }

  // 创建血管区域掩膜
  createVesselMask() {
    if (!this.options.enableVesselExtraction) {
      return null;
    }
    
    console.log('开始创建血管区域掩膜...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const totalPixels = rows * columns;
    const variations = new Float32Array(totalPixels);
    
    // 计算每个像素的TDC变化幅度
    for (let pixelIndex = 0; pixelIndex < totalPixels; pixelIndex++) {
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      variations[pixelIndex] = this.calculateTDCVariation(timeCurve);
    }
    
    // 计算变化幅度的阈值（使用Otsu方法的简化版本）
    const sortedVariations = Array.from(variations).sort((a, b) => a - b);
    const threshold = this.calculateOtsuThreshold(sortedVariations);
    
    console.log(`血管区域掩膜阈值: ${threshold.toFixed(4)}`);
    
    // 创建二值化掩膜
    const mask = new Uint8Array(totalPixels);
    for (let i = 0; i < totalPixels; i++) {
      mask[i] = variations[i] > threshold ? 1 : 0;
    }
    
    const vesselPixels = mask.reduce((sum, val) => sum + val, 0);
    console.log(`血管区域像素数: ${vesselPixels}/${totalPixels} (${(vesselPixels/totalPixels*100).toFixed(1)}%)`);
    
    return mask;
  }

  // 简化的Otsu阈值计算方法
  calculateOtsuThreshold(sortedValues) {
    if (sortedValues.length === 0) return 0;
    
    const total = sortedValues.length;
    let sum = 0;
    for (let i = 0; i < total; i++) {
      sum += sortedValues[i];
    }
    
    let sumB = 0;
    let wB = 0;
    let wF = 0;
    let varMax = 0;
    let threshold = 0;
    
    for (let i = 0; i < total; i++) {
      wB++;
      if (wB === 0) continue;
      
      wF = total - wB;
      if (wF === 0) break;
      
      sumB += sortedValues[i];
      const mB = sumB / wB;
      const mF = (sum - sumB) / wF;
      
      const varBetween = wB * wF * (mB - mF) * (mB - mF);
      
      if (varBetween > varMax) {
        varMax = varBetween;
        threshold = sortedValues[i];
      }
    }
    
    return threshold;
  }

  async calculateCBV() {
    // Cerebral Blood Volume - 脑血容量
    console.log('计算CBV (Cerebral Blood Volume)...');
    
    const { rows, columns } = this.pixelDataArray[0];
    const cbvData = new Float32Array(rows * columns);

    console.log(`开始计算CBV: ${rows}x${columns} 像素, 时间单位: ${this.timeUnit}`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取并预处理时间密度曲线
      const timeCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      const { correctedCurve } = this.parameterCalculator.preprocessTimeCurve(timeCurve);
      
      // 计算峰值、AUC和MTT
      const { peakValue } = this.parameterCalculator.calculatePeak(correctedCurve);
      const auc = this.parameterCalculator.calculateAUC(correctedCurve);
      const mtt = this.parameterCalculator.calculateMTT(correctedCurve);
      
      // CBV计算方法（多种可选）：
      // 方法1: 基于AUC (注释掉，可根据需要启用)
      // const cbv = auc / peakValue; 
      
      // 方法2: 基于中心容积定理 CBV = CBF × MTT / 60
      // const cbf = mtt > 0 ? (peakValue / mtt) * 60 : 0;
      // const cbv = cbf * mtt / 60;
      
      // 方法3: 简化的相对CBV计算（当前使用）
      const cbv = peakValue * 0.1; // 相对CBV，实际应用中需要校准
      
      cbvData[pixelIndex] = cbv;
    }

    // 创建并返回结果
    return this.createParameterResult(cbvData, {
      name: 'CBV',
      units: 'ml/100g',
      description: 'Cerebral Blood Volume (ml/100g)',
      physicalUnit: 'ml/100g',
      colorMap: 'plasma',
      precision: 2
    });
  }

  // 修改normalizeData方法，返回归一化后的数据以供显示
  normalizeDataForDisplay(data) {
    // 使用循环找到有效值的最小值和最大值，避免栈溢出
    let min = Infinity;
    let max = -Infinity;
    let validCount = 0;
    
    // 第一遍：找到有效值的范围
    for (let i = 0; i < data.length; i++) {
      const value = data[i];
      if (!isNaN(value) && isFinite(value)) {
        if (value < min) min = value;
        if (value > max) max = value;
        validCount++;
      }
    }
    
    // 如果没有有效值，返回全零数组
    if (validCount === 0) {
      const result = new Float32Array(data.length);
      result.fill(0);
      return result;
    }
    
    const range = max - min;
    
    // 如果范围为0，返回全0.5数组
    if (range === 0) {
      const result = new Float32Array(data.length);
      result.fill(0.5);
      return result;
    }
    
    // 第二遍：归一化数据
    const result = new Float32Array(data.length);
    for (let i = 0; i < data.length; i++) {
      const value = data[i];
      if (isNaN(value) || !isFinite(value)) {
        result[i] = 0;
      } else {
        result[i] = (value - min) / range;
      }
    }
    
    return result;
  }

  // 优化时间曲线平滑处理，避免数组操作导致的栈溢出
  smoothTimeCurve(curve, windowSize = 3) {
    if (curve.length <= windowSize) {
      // 对于小数组，直接复制
      const result = new Array(curve.length);
      for (let i = 0; i < curve.length; i++) {
        result[i] = curve[i];
      }
      return result;
    }
    
    const smoothed = new Array(curve.length);
    const halfWindow = Math.floor(windowSize / 2);
    
    for (let i = 0; i < curve.length; i++) {
      let sum = 0;
      let count = 0;
      
      const startJ = Math.max(0, i - halfWindow);
      const endJ = Math.min(curve.length - 1, i + halfWindow);
      
      for (let j = startJ; j <= endJ; j++) {
        sum += curve[j];
        count++;
      }
      
      smoothed[i] = sum / count;
    }
    
    return smoothed;
  }

  // 优化计算时间曲线统计特征的方法
  analyzeTimeCurve(curve) {
    const smoothed = this.smoothTimeCurve(curve);
    const baseline = smoothed[0];
    
    // 使用循环而不是map来基线校正
    const corrected = new Array(smoothed.length);
    let peak = -Infinity;
    let peakIndex = 0;
    
    for (let i = 0; i < smoothed.length; i++) {
      corrected[i] = smoothed[i] - baseline;
      if (corrected[i] > peak) {
        peak = corrected[i];
        peakIndex = i;
      }
    }
    
    // 计算上升时间（10%-90%峰值）
    const rise10 = peak * 0.1;
    const rise90 = peak * 0.9;
    
    let riseStart = 0, riseEnd = peakIndex;
    for (let i = 0; i < corrected.length; i++) {
      if (corrected[i] >= rise10 && riseStart === 0) riseStart = i;
      if (corrected[i] >= rise90) { riseEnd = i; break; }
    }
    
    // 计算AUC，使用循环
    let aucSum = 0;
    for (let i = 0; i < corrected.length; i++) {
      aucSum += Math.max(0, corrected[i]);
    }
    
    return {
      baseline,
      peak,
      peakIndex,
      riseTime: riseEnd - riseStart,
      auc: aucSum
    };
  }

  // 应用中值滤波减少噪声
  medianFilter(data, width, height, kernelSize = 3) {
    const filtered = new Float32Array(data.length);
    const halfKernel = Math.floor(kernelSize / 2);
    
    for (let y = 0; y < height; y++) {
      for (let x = 0; x < width; x++) {
        const values = [];
        
        // 提取内核区域的值
        for (let ky = -halfKernel; ky <= halfKernel; ky++) {
          for (let kx = -halfKernel; kx <= halfKernel; kx++) {
            const nx = x + kx;
            const ny = y + ky;
            
            if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
              values.push(data[ny * width + nx]);
            }
          }
        }
        
        // 计算中值
        values.sort((a, b) => a - b);
        const medianIndex = Math.floor(values.length / 2);
        filtered[y * width + x] = values[medianIndex];
      }
    }
    
    return filtered;
  }

  // 归一化数据到0-1范围（兼容性方法）
  normalizeData(data) {
    return this.normalizeDataForDisplay(data);
  }

  // 获取统计信息 - 优化以避免栈溢出
  getStatistics(data) {
    const { min, max } = this.getMinMax(data);
    
    // 计算均值，使用循环
    let sum = 0;
    for (let i = 0; i < data.length; i++) {
      sum += data[i];
    }
    const mean = sum / data.length;
    
    // 计算方差，使用循环
    let varianceSum = 0;
    for (let i = 0; i < data.length; i++) {
      const diff = data[i] - mean;
      varianceSum += diff * diff;
    }
    const variance = varianceSum / data.length;
    const std = Math.sqrt(variance);
    
    return {
      min,
      max,
      mean,
      std,
      count: data.length
    };
  }

  // ===================== 最大斜率法参数计算 =====================

  /**
   * 使用最大斜率法计算所有参数
   * @returns {Object} 包含所有血流参数的对象
   */
  async calculateMaximumSlopeParameters(reportProgress = null) {
    console.log('开始最大斜率法参数计算...');
    
    if (!this.options.arterialInputPoint) {
      throw new Error('最大斜率法需要动脉输入点，请先标记动脉输入点');
    }

    // 提取动脉输入函数
    if (reportProgress) reportProgress(30, '正在提取动脉输入函数...');
    const arterialCurve = ParameterCalculator.extractArterialInputFunction(
      this.pixelDataArray, 
      this.options.arterialInputPoint
    );
    
    if (arterialCurve.length === 0) {
      throw new Error('无法提取动脉输入函数，请检查动脉输入点位置');
    }

    const { rows, columns } = this.pixelDataArray[0];
    
    // 使用统一的参数计算方法，每个参数约占10%的进度
    if (reportProgress) reportProgress(40, '正在计算峰值...');
    const peak = await this.calculateMaximumSlopeParameter('peak', arterialCurve);
    
    if (reportProgress) reportProgress(50, '正在计算 TTP (达峰时间)...');
    const ttp = await this.calculateMaximumSlopeParameter('ttp', arterialCurve);
    
    if (reportProgress) reportProgress(60, '正在计算 AUC (曲线下面积)...');
    const auc = await this.calculateMaximumSlopeParameter('auc', arterialCurve);
    
    if (reportProgress) reportProgress(70, '正在计算 PH (峰值高度)...');
    const ph = await this.calculateMaximumSlopeParameter('ph', arterialCurve);
    
    if (reportProgress) reportProgress(80, '正在计算 MTT (平均通过时间)...');
    const mtt = await this.calculateMaximumSlopeParameter('mtt', arterialCurve);
    
    if (reportProgress) reportProgress(90, '正在计算 CBF (脑血流)...');
    const cbf = await this.calculateMaximumSlopeParameter('cbf', arterialCurve);
    
    if (reportProgress) reportProgress(95, '正在计算 CBV (脑血容量)...');
    const cbv = await this.calculateMaximumSlopeParameter('cbv', arterialCurve);

    return { 
      peak: peak,    // 峰值
      ttp: ttp,      // 时间到峰值
      auc: auc,      // 曲线下面积
      ph: ph,        // 峰值高度
      mtt: mtt,      // 平均通过时间
      cbf: cbf,      // 脑血流量
      cbv: cbv       // 脑血容量
    };
  }

  /**
   * 计算单个最大斜率法参数
   * @param {string} parameterName 参数名称 (peak, ttp, auc, mtt, cbf, cbv)
   * @param {Array} arterialCurve 动脉输入函数
   * @returns {Object} 参数计算结果
   */
  async calculateMaximumSlopeParameter(parameterName, arterialCurve) {
    console.log(`计算最大斜率法参数: ${parameterName}...`);
    
    const { rows, columns } = this.pixelDataArray[0];
    const parameterData = new Float32Array(rows * columns);

    console.log(`开始计算${parameterName}: ${rows}x${columns} 像素`);

    for (let pixelIndex = 0; pixelIndex < rows * columns; pixelIndex++) {
      // 提取组织时间密度曲线
      const tissueCurve = ParameterCalculator.extractTimeCurve(this.pixelDataArray, pixelIndex);
      
      // 计算最大斜率参数
      const params = this.parameterCalculator.calculateMaximumSlopeParameters(
        tissueCurve, 
        arterialCurve, 
        this.timeArray
      );
      
      // 根据参数名称提取对应的值
      parameterData[pixelIndex] = params[parameterName] || 0;
    }

    // 参数配置
    const parameterConfigs = {
      peak: {
        name: 'Peak',
        units: 'HU',
        description: 'Peak Enhancement (Maximum Slope Method)',
        physicalUnit: 'Hounsfield Units',
        colorMap: 'hot',
        precision: 1
      },
      ttp: {
        name: 'TTP',
        units: 's',
        description: 'Time to Peak (Maximum Slope Method)',
        physicalUnit: 'seconds',
        colorMap: 'jet',
        precision: 2
      },
      auc: {
        name: 'AUC',
        units: 'HU·s',
        description: 'Area Under Curve (Maximum Slope Method)',
        physicalUnit: 'HU·seconds',
        colorMap: 'plasma',
        precision: 1
      },
      ph: {
        name: 'PH',
        units: 'intensity',
        description: 'Peak Height (Maximum Slope Method)',
        physicalUnit: 'Intensity Units',
        colorMap: 'jet',
        precision: 1
      },
      mtt: {
        name: 'MTT',
        units: 's',
        description: 'Mean Transit Time (Maximum Slope Method)',
        physicalUnit: 'seconds',
        colorMap: 'viridis',
        precision: 2
      },
      cbf: {
        name: 'CBF',
        units: 'ml/100g/min',
        description: 'Cerebral Blood Flow (Maximum Slope Method)',
        physicalUnit: 'ml/100g/min',
        colorMap: 'hot',
        precision: 2
      },
      cbv: {
        name: 'CBV',
        units: 'ml/100g',
        description: 'Cerebral Blood Volume (Maximum Slope Method)',
        physicalUnit: 'ml/100g',
        colorMap: 'plasma',
        precision: 2
      }
    };

    const config = parameterConfigs[parameterName] || parameterConfigs.peak;

    // 创建并返回结果
    return this.createParameterResult(parameterData, config);
  }
}

export { ImageProcessor }; 